package com.demo.webapp.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * 组件抽象实现
 * 提供组件的基础访问方法
 * 其他组件实现该抽象类
 * 
 * @author ryuu.kk
 * 
 */
public abstract class ComponentBase implements Component {

	/**
	 * 版本序列化ID
	 */
	private static final long serialVersionUID = -5013180100766003000L;
	//~ Static fields/initializers =============================================
    protected static ComponentBase[] _emptyComponent = new ComponentBase[0];
	//~ 组件的基础属性   **************************************************************************************************************
	/** ID **/
	protected String id;

	/** name **/
	protected String name;

	/** component Type **/
	protected String type;

	/** 组件对象标题. */
	protected String title;

	/** 组件对象描述. **/
	protected String description;
	
	/** parent Component **/
	protected ComponentBase parent;

	/** children Component **/
	protected List<ComponentBase> subComponents = Collections.synchronizedList(new ArrayList<ComponentBase>());

	//~ 组件的访问许可  ***********************************************************
	/** 组件的访问许可. */
	protected String permission;

	/** 
	 * 新增功能
	 * at 2013-04-07 新增功能ID
	 **/
	protected Long funid;
	
	//~ 组件的访问地址  ***********************************************************
	// 优先级为 location -> page -> forward -> target
	/** 组件的访问地址,该地址允许使用EL表达式'${...}',实现组件的动态地址 */
	protected String location;

	/** Holds value of property page. */
	protected String page;

	/** Holds value of property forward. */
	protected String forward;

	/** 在何处打开目标 URL ('_blank', '_parent', '_self', '_top'(default _blank)) */
	protected String target;

	/** component url **/
	protected String url;

	//~ 组件的展示属性  ***********************************************************
	/** 对齐方式: 'left','right','top','bottom' ... 其他 */
	protected String align;

	/** Holds value of property width. */
	protected String width;

	/** component altImage. */
	protected String altImage;

	/** Holds value of property height. */
	protected String height;

	/** menu的image路径. */
	protected String image;

	/** component toolTip */
	protected String toolTip;

	/** menu的css样式**/
	protected String css;
	
	//~ 组件的js事件  ***********************************************************
	/** Holds value of property onclick. */
	protected String onclick;

	/** Holds value of property ondblclick. */
	protected String ondblclick;

	/** Holds value of property onmouseout. */
	protected String onmouseout;

	/** Holds value of property onmouseover. */
	protected String onmouseover;

	/**
	 * 添加组件
	 * @param component 组件模型
	 */
	public void addComponent(ComponentBase component) {
		if (subComponents == null) {
			subComponents = Collections.synchronizedList(new ArrayList<ComponentBase>());
		}
		if ((component.getName() == null)
				|| (component.getName().equals(""))) {
			component.setName(this.name + subComponents.size());
		}
		if (!subComponents.contains(component)) {
			subComponents.add(component);
			component.setParent(this);
		}
	}

	/**
	 * 添加组件
	 * @param components 组件数组
	 */
    public void setComponents(ComponentBase[] components) {
        for (int i = 0; i < components.length; i++) {
            ComponentBase component = components[i];
            this.subComponents.add(component);
            component.setParent(this);
        }
    }

    public void setParent(ComponentBase parentComponent) {
        if (parentComponent != null) {
            if (!parentComponent.getSubComponents().contains(this)) {
            	parentComponent.addComponent(this);
            }
        }
        this.parent = parentComponent;
    }

	/**
	 * 返回容器的子容器 如果不存在子容器，则返回null
	 * 
	 * @return Components
	 */
	public List<ComponentBase> getSubComponents() {
		return this.subComponents;
	}
    /**
     * 移除所有子组件
     */
    public void removeComponents() {
		for (Iterator<ComponentBase> iterator = this.getSubComponents().iterator(); 
				iterator.hasNext();) {
			ComponentBase child = iterator.next();
			child.setParent(null);
			iterator.remove();
		}
    }
	/**
	 * 返回容器的父级容器
	 * 
	 * @return 父容器
	 */
	public ComponentBase getParent() {
		return this.parent;
	}
	
	/**
	 * 返回组件针对定点组件的层级Level
	 * 
	 * @return 组件级别Level
	 */
	public int getLevel() {
		return getLevel(this, 0);
	}
	
	/**
	 * 返回组件针对定点组件的层级Level
	 * 
	 * @param base 组件
	 * @param currentLevel 当前级别
	 * @return 组件级别Level
	 */
	public int getLevel(ComponentBase base, int currentLevel) {
		//整个组件中从跟节点向下的层级(节点深度)
		int depth = currentLevel + 1;
		if (base != null) {
			getLevel(base.getParent(), depth);
		}
		return depth;
	}
    /**
     * 返回容器的深度
     * 
     * @return 容器深度
     */
    public int getDepth() {
        return getDepth(this, 0);
    }
    /**
     * 返回组件深度.
     * 当前组件下最深的那个节点深度
     * 
     * @param component 组件
     * @param currentDepth 当前深度
     * @return 当前组件的包含容器中最深的深度
     */
    protected int getDepth(ComponentBase component, int currentDepth) {
        int depth = currentDepth + 1;

        List<ComponentBase> subs = component.getSubComponents();
        if (subs != null) {
            for (int a = 0; a < subs.size(); a++) {
                int depthx = getDepth(subs.get(a), currentDepth + 1);
                if (depth < depthx)
                    depth = depthx;
            }
        }
        return depth;
    }
    
	@Override
	public String getId() {
		return this.id;
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public String getType() {
		return this.type;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	@Override
	public String getUrl() {
		return targetUrl(url);
	}
	public String targetUrl(String url) {
		if (url == null || "".equals(url.trim())) {
			return this.target;
		}
		return url;
	}
	// ~=============== setter methods ===============
    
	public void setId(String id) {
		this.id = id;
	}

	public void setType(String type) {
		this.type = type;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getTitle() {
		return this.title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getAlign() {
		return align;
	}

	public void setAlign(String align) {
		this.align = align;
	}

	public String getAltImage() {
		return altImage;
	}

	public void setAltImage(String altImage) {
		this.altImage = altImage;
	}

	public String getForward() {
		return forward;
	}

	public void setForward(String forward) {
		this.forward = forward;
	}

	public String getHeight() {
		return height;
	}

	public void setHeight(String height) {
		this.height = height;
	}

	public String getImage() {
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public String getCss() {
		return css;
	}

	public void setCss(String clazz) {
		this.css = clazz;
	}

	public String getOnclick() {
		return onclick;
	}

	public void setOnclick(String onclick) {
		this.onclick = onclick;
	}

	public String getOndblclick() {
		return ondblclick;
	}

	public void setOndblclick(String ondblclick) {
		this.ondblclick = ondblclick;
	}

	public String getOnmouseout() {
		return onmouseout;
	}

	public void setOnmouseout(String onmouseout) {
		this.onmouseout = onmouseout;
	}

	public String getOnmouseover() {
		return onmouseover;
	}

	public void setOnmouseover(String onmouseover) {
		this.onmouseover = onmouseover;
	}

	public String getPage() {
		return page;
	}

	public void setPage(String page) {
		this.page = page;
	}

	public String getTarget() {
		return target;
	}

	public void setTarget(String target) {
		this.target = target;
	}

	public String getToolTip() {
		return toolTip;
	}

	public void setToolTip(String toolTip) {
		this.toolTip = toolTip;
	}

	public String getWidth() {
		return width;
	}

	public void setWidth(String width) {
		this.width = width;
	}

	public void setSubComponents(List<ComponentBase> subComponents) {
		this.subComponents = subComponents;
	}

	public String getPermission() {
		return permission;
	}

	public void setPermission(String permission) {
		this.permission = permission;
	}

	public Long getFunid() {
		return funid;
	}
	public void setFunid(Long funid) {
		this.funid = funid;
	}
}